AWS IoT Device SDK for Pythonを使ってAWS IoTのジョブ機能を試してみる
どうも!大阪オフィスの西村祐二です。
ファームウェアの更新などで複数台のデバイスまとめて同じ命令をしたい事があると思います。
それを実現するためのジョブという機能がAWS IoTにはサポートされています。
AWS IoT Device SDK for Pythonにはジョブのサンプルプログラムが提供されているので、それを使ってAWS IoTのジョブ機能を試してみたいと思います。
機能検証を行うにあたりデバイスとして今回、1台のラズパイを利用します。
ジョブ機能とは
AWS IoTに接続された、1つ以上のデバイスに一連のリモート操作を定義できます。たとえば、あるグループに属するデバイスに対して、アプリケーションやファームウェア更新のダウンロードとインストール、再起動、証明書のローテーション、またはリモートトラブルシューティングオペレーションの実行を指示するジョブを定義できます。
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-jobs.html
環境
- RaspberryPi 3 Model B
- Linux raspberrypi 4.9.30-v7+ #1001 SMP Fri May 26 16:09:18 BST 2017 armv7l GNU/Linux
- aws-iot-device-sdk-python:v1.4.0
- python2.7
事前準備
下記ブログを参考に、RaspberryPiからAWS IoTへと通信できるようにしておいてください。
ラズパイ側に配置した証明書類は下記のように構造にしています。
├── cert <= ディレクトリ作成 │ ├── cert.crt <= 接続時に利用する証明書を設置 │ ├── private.key <= 接続時に利用する証明書を設置 │ ├── public.key <= 接続時に利用する証明書を設置 │ └── rootCA.pem <= 接続時に利用する証明書を設置 ├── samples │ ├── ThingShadowEcho │ │ └── ThingShadowEcho.py │ ├── basicPubSub │ │ ├── basicPubSub.py │ │ ├── basicPubSubAsync.py │ │ ├── basicPubSub_APICallInCallback.py │ │ └── basicPubSub_CognitoSTS.py │ ├── basicShadow │ │ ├── basicShadowDeltaListener.py │ │ └── basicShadowUpdater.py │ ├── greengrass │ │ └── basicDiscovery.py │ └── jobs │ └── jobsSample.py
ジョブドキュメントを作成
デバイス側で実行したい命令を記載したJSON形式のドキュメントを作成します。
今回はテストということで、シンプルな形にしています。
{ "job-key": "job" }
S3にジョブドキュメントを配置
上記で作成した、ジョブドキュメントをS3バケットに配置しておきます。
AWS IoTでジョブを作成
▼ジョブから作成を選択します。
▼カスタムジョブの作成を選択します。
▼ジョブID、ジョブを適用するデバイス、ジョブドキュメントを指定します。
今回はテストということで、ジョブを適用するのは1台のラズパイとしています。
▼ジョブタイプをスナップショットに設定して、ジョブを作成します。
▼作成されたジョブを確認してみます。
ジョブの進行状況がわかります。
ラズパイ側でサンプルプログラムを実行してみる
注意点として、通常とエンドポイントが異なります。ジョブ用のエンドポイントを確認しておき、それを指定する必要があります。
$ aws iot describe-endpoint --endpoint-type iot:Data
{
"endpointAddress": "xxxxxxxxx.iot.ap-northeast-1.amazonaws.com"
}
では、サンプルプログラムを実行してみます。
$ ls jobsSample.py $ python jobsSample.py \ -e xxxx.iot.ap-northeast-1.amazonaws.com \ -r ../../cert/rootCA.pem \ -c ../../cert/cert.crt \ -k ../../cert/private.key \ -n <thing name> . . . 2018-09-24 23:08:19,341 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation... Starting to process jobs... 2018-09-24 23:08:19,353 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish... 2018-09-24 23:08:19,355 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback... 2018-09-24 23:08:19,402 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event 2018-09-24 23:08:19,404 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event 2018-09-24 23:08:19,405 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event 2018-09-24 23:08:19,405 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback... 2018-09-24 23:08:19,406 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation... 2018-09-24 23:08:19,407 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event Executing job ID, version, number: test-job, 2, 1 With jobDocument: {"job-key": "job"} 2018-09-24 23:08:19,410 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish... 2018-09-24 23:08:19,411 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback... 2018-09-24 23:08:19,413 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback... 2018-09-24 23:08:19,445 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event 2018-09-24 23:08:19,447 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event 2018-09-24 23:08:19,448 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event 2018-09-24 23:08:19,449 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback... 2018-09-24 23:08:19,450 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation... 2018-09-24 23:08:19,451 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event 2018-09-24 23:08:19,452 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback... 2018-09-24 23:08:19,759 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event 2018-09-24 23:08:19,760 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event Notify next saw no execution 2018-09-24 23:08:19,763 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback... Done processing jobs Stats: {"jobsSucceeded": 1, "jobsStarted": 1, "jobsRejected": 0} 2018-09-24 23:08:21,356 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync disconnect... 2018-09-24 23:08:21,357 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing async disconnect... . . .
26行目のjob ID, version, number: test-job, 2, 1
は「test-job」がジョブID、「2」がバージョン、「1」が実行番号となります。
27行目で{"job-key": "job"}
が出力されており、設定したジョブドキュメントをデバイス側(ラズパイ側)で取得できていることがわかります。実際はここのところで、アプリケーションやファームウェア更新のダウンロードとインストール、再起動、証明書のローテーションなどの処理を実装していくことになると思います。
▼AWS IoTのマネージメントコンソールからジョブのステータスを確認してみると、こちらも「成功」となっています。
さいごに
いかがだったでしょうか。
とりあえず動かしてみたという感じですが、ラズパイとAWS IoT Device SDK for Pythonを使ってAWS IoTのジョブ機能を試してみました。次回はもっと実践的な内容を想定して試してみたいと思います。
誰かの参考になれば幸いです。